import math
import os
import sys
from typing import Optional

from PyQt5.QtCore import QSize
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel, QVBoxLayout, QHBoxLayout, QApplication, QLayout, QComboBox

from ClientUi.controls.ResizablePicture import ResizablePicture
from sengo_common.pyqt_imshow import *


class ImageBoxWidget(QWidget):
    __resultOKColor = 'rgb(0,254,102)'
    __resultNGColor = 'rgb(255,0,0)'

    def __init__(self):
        super().__init__()
        vLayout = QVBoxLayout()
        cap = self.__createCaptionWidget()
        infos = self.__createResultInfosWidget()
        #self.camera_image = ResizablePicture(self)
        self.camera_image = UI_ImageView(self)
        self.camera_image.setObjectName('LabelImage')
        self.camera_image.setMinimumSize(200, 150)
        vLayout.addWidget(cap)
        vLayout.addWidget(infos)
        vLayout.addWidget(self.camera_image)
        vLayout.setContentsMargins(0, 0, 0, 0)
        vLayout.setSpacing(0)
        self.setLayout(vLayout)

    def SetTitle(self, title: str):
        self.__Title.setText(title)

    def SetResult(self, bOk: Optional[bool]):
        if bOk is None:
            self.__camera_result.setText('')
            return
        if bOk:
            self.__camera_result.setText('OK')
            self.__camera_result.setStyleSheet(f"color: {self.__resultOKColor};")
        else:
            self.__camera_result.setText('NG')
            self.__camera_result.setStyleSheet(f"color: {self.__resultNGColor};")

    def SetPixmap(self, pixmap: Optional[QPixmap]):
        self.camera_image.setPixmap(pixmap)

    def GetImgLabelSize(self) -> QSize:
        return self.camera_image.size()

    def __createCaptionWidget(self):
        widget = QWidget()
        widget.setObjectName('VBoxCaption')
        widget.setFixedHeight(30)
        hLayout = QHBoxLayout()
        self.__Title = QLabel(self)
        self.__Title.setObjectName('VBoxTitle')
        icon = QLabel()
        icon.setObjectName('VBoxIcon')
        hLayout.addWidget(icon)
        hLayout.addWidget(self.__Title)
        hLayout.setContentsMargins(5, 0, 5, 0)
        widget.setLayout(hLayout)
        return widget

    def __createResultInfosWidget(self):
        widget = QWidget()
        cameraInfos = QGridLayout()
        lbResult = QLabel('结果: ', self)
        lbResult.setFixedHeight(40)
        lbResult.setFixedWidth(65)
        lbResult.setContentsMargins(25, 0, 0, 0)
        self.__camera_result = QLabel('', self)
        self.__camera_result.setObjectName('LabelResult')
        self.__camera_result.setFixedHeight(40)
        # cameraInfos 中还可以添加其他需要显示的信息
        cameraInfos.addWidget(lbResult, 0, 0)
        cameraInfos.addWidget(self.__camera_result, 0, 1)
        widget.setFixedHeight(60)
        widget.setLayout(cameraInfos)
        return widget


def layout_it(obj, level):
    hv_layout = [QHBoxLayout, QVBoxLayout]
    if isinstance(obj, list):
        out = hv_layout[level % 2]()
        for x in obj:
            a = layout_it(x, level+1)
            if 'Layout' in str(type(a)):
                out.addLayout(a)
            else:
                out.addWidget(a)
        return out
    return obj

def deleteLayout(lay: QLayout, bKeepSubItem: bool):
    if lay is None:
        return
    while (item := lay.takeAt(0)) is not None:
        if item.layout() is not None:
            if bKeepSubItem:
                item.setParent(None)
            else:
                deleteLayout(item, bKeepSubItem)
        elif item.widget() is not None:
            if bKeepSubItem:
                item.setParent(None)
            else:
                del item

    del lay

class ImagePanelsGroupWidget(QWidget):
    __maxPanelNum = 16
    __cameraLayout = None
    __mainLayout = None

    def __init__(self, curShowPanelNum: int, parent: Optional[QWidget] = None):
        super().__init__(parent)
        self.__curShowPanelNum = curShowPanelNum
        #self.__maxPanelNum = maxPanelsNum
        if self.__curShowPanelNum > self.__maxPanelNum:
            self.__curShowPanelNum = self.__maxPanelNum
        self.__mainLayout = QVBoxLayout()
        self.__mainLayout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(self.__mainLayout)
        self.__initUI()

    def __initUI(self):
        self.imgBoxs = []
        for i in range(self.__maxPanelNum):
            camera_box = self.__createImgWidget()
            camera_box.setVisible(False)
            self.imgBoxs.append(camera_box)
        self.__setImgLayout(self.__curShowPanelNum)

    def __setImgLayout(self, num: int):
        showCameras = []
        for i in range(num):
            showCameras.append(self.imgBoxs[i])
        camlays = {
            3: [[0, 1], [2, ]],
            4: [[0, 1], [2, 3]],
            5: [[0, 1, 2], [3, 4]],
            6: [[0, 1, 2], [3, 4, 5]],
            7: [[0, 1, 2, 3], [4, 5, 6]],
            8: [[0, 1, 2, 3], [4, 5, 6, 7]],
            9: [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
            10: [[0, 1, 2], [3, 4, 5], [6, 7, 8, 9]],
        }
        level = 1
        if num in camlays:
            lays = camlays[num]
        else:
            if num < 4:
                lays = [i for i in range(num)]
                level = 0
            else:
                row = int(math.sqrt(num))
                lays = [[j for j in range(int(round(i * num / row)),
                                          min(int(round((i + 1) * num / row)),
                                              num))] for i in range(row)]

        def lay2cl(cl, laysTmp):
            if isinstance(laysTmp, list):
                return [lay2cl(cl, x) for x in laysTmp]
            elif isinstance(laysTmp, int):
                return cl[laysTmp]
            return None

        cl_lays = lay2cl(showCameras, lays)
        cameras_layout = layout_it(cl_lays, level=level)
        cameras_layout.setContentsMargins(0, 0, 0, 0)
        cameras_layout.setSpacing(2)
        #print(f'__setImgLayout {len(showCameras)}')
        if self.__cameraLayout is not None:
             self.__mainLayout.removeItem(self.__cameraLayout)
        self.__mainLayout.addLayout(cameras_layout)
        #self.setLayout(cameras_layout)
        self.__cameraLayout = cameras_layout
        for i in range(num):
            self.imgBoxs[i].setVisible(True)
        #self.update()

    def __createImgWidget(self):
        w = ImageBoxWidget()
        w.setObjectName('PanelCamera')
        return w

    # 设置图像窗口标题
    def SetImgBoxTitleByIndex(self, index: int, title: str):
        self.imgBoxs[index].SetTitle(title)

    # 更新图像及结果
    def SetImgAndResultByIndex(self, index: int, img: QPixmap, bOk: bool):
        self.imgBoxs[index].SetPixmap(img)
        self.imgBoxs[index].SetResult(bOk)

    # 清除图像及结果信息
    def ClearImgAndResultByIndex(self, index: int):
        self.imgBoxs[index].SetPixmap(None)
        self.imgBoxs[index].SetResult(None)

    def GetImgLabelSize(self, index: int) -> QSize:
        return self.imgBoxs[index].GetImgLabelSize()

    def SetShowImgNum(self, num: int):
        if self.__curShowPanelNum == num:
            return
        self.__ClearImgLayout()

        self.__curShowPanelNum = num
        self.__setImgLayout(self.__curShowPanelNum)


    def __ClearImgLayout(self):
        if self.__cameraLayout is not None:
            for i in range(len(self.imgBoxs)):
                self.imgBoxs[i].setVisible(False)
                self.imgBoxs[i].setParent(None)
            self.__mainLayout.removeItem(self.__cameraLayout)
            # deleteLayout(self.__cameraLayout, False)
            self.__cameraLayout = None



class TestWidget(QWidget):
    def __init__(self):
        super().__init__()
        v = QVBoxLayout()
        self.setLayout(v)
        cmb = QComboBox()
        cmb.addItems(['1','2','3','4','5','6'])
        cmb.setCurrentIndex(3)
        v.addWidget(cmb)
        self.__imgs = ImagePanelsGroupWidget(4, 6)
        v.addWidget(self.__imgs)
        cmb.currentIndexChanged.connect(self.__cmbChanged)

    def __cmbChanged(self, index):
        #self.__imgs.__ClearImgLayout()
        self.__imgs.SetShowImgNum(index+1)



if __name__ == "__main__":
    app = QApplication(sys.argv)
    try:
        current_path = os.path.abspath(__file__)
        path = os.path.dirname(current_path)
        path = os.path.dirname(path)
        app.setStyleSheet(open(f'{path}/styleSheet.qss', encoding='utf-8').read())
        # app.setStyleSheet(
        #     '''
        #     ImageBoxWidget{border: 1px solid green;}
        #     QLabel{border: 1px solid blue;}
        #     '''
        # )
        window = TestWidget()
        window.setMinimumWidth(200)
        window.setMinimumHeight(400)
        window.showNormal()
        sys.exit(app.exec_())

    except Exception as e:
        print(e)